﻿using System;
using Microsoft.Xna.Framework;

namespace Game1942.Library.Background
{
    public class Point
    {
        private int x;
        private int y;

        public static readonly Point UpPoint = new Point(0,-(Constants.Screen.Height / Constants.Screen.Resolution));
        public static readonly Point DownPoint = new Point(0, (Constants.Screen.Height / Constants.Screen.Resolution));
        public static readonly Point LeftPoint = new Point(-(Constants.Screen.Width / Constants.Screen.Resolution),0);
        public static readonly Point RightPoint = new Point((Constants.Screen.Width / Constants.Screen.Resolution),0);
    
		// Constructors
        public Point(int xValue , int yValue)
        {
            x = xValue;
            y = yValue;
        }
        public Point()
        {
            x = 0;
            y = 0;
        }

        public Point(Point point)
        {
            x = point.x;
            y = point.y;
        }

        // Individual getters and setters
        public int X
        {
            get { return x; }
            set { x = value; }
        }
        public int Y
        {
            get { return y; }
            set { y = value; }
        }
        
		// Overloading/implementing of the common operators we will use
		// Comparation
        public static bool operator == (Point p1, Point p2)
        {
            if (object.ReferenceEquals(p1, p2))
                return true;
            if (((object)(p1) == null) || ((object)(p2) == null))
                return false;
            return ((p1.x == p2.x) && (p1.y == p2.y));
        }
		
		// Comparation with negation
        public static bool operator != (Point p1, Point p2)
        {
            if (object.ReferenceEquals(p1, p2))
                return true;
            if (((object)(p1) == null) || ((object)(p2) == null))
                return false;
            return ((p1.x != p2.x) && (p1.y != p2.y));
        }
		
		// Greater than or equal comparison
        public static bool operator >= (Point p1, Point p2)
        {
            if (object.ReferenceEquals(p1, p2))
                return true;

            if (((object)(p1) == null) || ((object)(p2) == null))
                return false;
            
            return ((p1.X >= p2.X) && (p1.Y >= p2.Y));
                 
        }

		// Less than or equal comparison
        public static bool operator <=(Point p1, Point p2)
        {
            if (object.ReferenceEquals(p1, p2))
                return true;

            if (((object)(p1) == null) || ((object)(p2) == null))
                return false;

            return ((p1.X <= p2.X) && (p1.Y <= p2.Y));
        }

		// Greater than comparison
        public static bool operator >(Point p1, Point p2)
        {
            if (ReferenceEquals(p1, p2) || ((object)(p1) == null) || ((object)(p2) == null))
                return false;

            return ((p1.X > p2.X) && (p1.Y > p2.Y));
        }

		// Less than comparison
        public static bool operator <(Point p1, Point p2)
        {
            if (ReferenceEquals(p1, p2) || ((object)(p1) == null) || ((object)(p2) == null))
                return false;

            return ((p1.X < p2.X) && (p1.Y < p2.Y));
        }

		// Explicit addition 
        public void Plus (Point point)
        {
            if ((object)point == null)
                throw new ArgumentNullException();
            x += point.X;
            y += point.Y;
        }

		// Explicit equating
        public override bool Equals(System.Object obj)
        {
            if (obj == null) { return false; }

            // If parameter cannot be cast to Point return false
            Point p = obj as Point;
            if ((System.Object)p == null) { return false; }

            return (x == p.x) && (y == p.y);
        }
		
		// Simple hash algorithm
        public override int GetHashCode() { return x ^ y; }

		// Inverting of a point
        public Point Inverse()
        {
            x = -x;
            y = -y;
            return this;
        }

        public Vector2 ToVector2()
        {
            return (new Vector2(x, y));
        }

        public bool BelongsTo(Background map)
        {
            var dimension = map.GetDimension();
            return ((x >= 0) && (x < dimension.x) && (y >= 0) && (y < dimension.y));
        }
    }
}
